package com.um.jdy.app.queue.listener;

import com.um.jdy.app.shop.manager.ShopOrderManager;
import com.um.jdy.app.queue.enums.DelayedQueueKey;
import com.um.jdy.app.queue.service.RedissonDelayedQueueService;
import com.um.jdy.common.shop.entity.po.Order;
import com.um.jdy.common.shop.service.ShopOrderService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.RedissonShutdownException;
import org.redisson.api.RBlockingDeque;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.util.concurrent.Executors;

/**
 * @Title
 * @Description
 * @Author renjunwei
 * @Date 2024/4/27 11:57
 */
@Slf4j
@Component
public class OrderDelayedQueueListener {

    @Resource
    private RedissonDelayedQueueService redissonDelayedQueueService;

    @Resource
    ShopOrderManager shopOrderManager;

    @Resource
    ShopOrderService shopOrderService;

    private boolean destroyed = false;

    @PreDestroy
    public void destroy() {
        destroyed = true;
        log.info("[Redisson]队列监听器停止");
    }

    @PostConstruct
    public void closeGroupListener() {
        Executors.newSingleThreadExecutor().execute(() -> {
            while (!destroyed){
                RBlockingDeque<String> blockingDeque = redissonDelayedQueueService.getQueue(DelayedQueueKey.CloseGroup.name());
                try {
                    String id = blockingDeque.take();
                    shopOrderManager.closeGroup(id);
                    log.info("延时队列关闭拼团:{}", id);
                } catch (RedissonShutdownException e) {
                    log.warn("[Redisson]队列消费错误: {}", e.getMessage());
                    break;
                } catch (Exception e) {
                    log.error("[Redisson]队列消费错误", e);
                }
            }
        });
    }

    @PostConstruct
    public void cancelOrderListener() {
        Executors.newSingleThreadExecutor().execute(() -> {
            while (!destroyed){
                RBlockingDeque<String> blockingDeque = redissonDelayedQueueService.getQueue(DelayedQueueKey.CancelOrder.name());
                try {
                    String id = blockingDeque.take();
                    Order order = shopOrderService.getRow(id);
                    if(null != order){
                        shopOrderManager.cancel(id, order.getMemberUserId());
                        log.info("延时队列取消订单:{}", order.getOrderNo());
                    }
                } catch (RedissonShutdownException e) {
                    log.warn("[Redisson]队列消费错误: {}", e.getMessage());
                    break;
                } catch (Exception e) {
                    log.error("[Redisson]队列消费错误", e);
                }
            }
        });
    }
}
